const express = require('express');
const cors = require('cors');
const WebSocket = require('ws');
const ASRClient = require('./asrClient.js');
const { log } = require('console');
const fs = require('fs').promises; // 使用 Promise API

const app = express();
app.use(cors());
app.use(express.json({ limit: '100mb' }));

const PORT = 3000;
const ASR_SERVER_URL = 'ws://localhost:8888';

// Initialize ASR client
const g_ASRClient = new ASRClient(ASR_SERVER_URL);

// API endpoints
console.log("Defining apis...")

app.get('/', (req, res) => {
  console.log('Hello, getting /!');
});
/*app.post('/api', (req, res) => {
  console.log('Hello, posting /api!');
}); // OK */
app.post('/api/select-mode', (req, res) => {
  console.log('/api/select-mode')
  const { mode } = req.body;
  console.log("Selecting mode!")
  g_ASRClient.selectMode(mode);
  
  res.json({ status: 'Mode selection sent' });
});


async function checkFileExists(filePath) {
  try {
    await fs.access(filePath);
    return true; // 文件存在
  } catch (error) {
    if (error.code === 'ENOENT') {
        return false; // 文件不存在
    }
    throw error; // 其他错误（如权限问题）
  }
}

app.post('/api/set-audio-params', (req, res) => {
  console.log("/api/set-audio-params");
  const { sample_rate, bit_depth, num_channels } = req.body; 
  console.log("Setting audio params..."+sample_rate+" "+bit_depth+" "+num_channels); //OK
  g_ASRClient.setAudioParams(sample_rate, bit_depth , num_channels);
  res.json({ status: 'Audio params sent' });
});

/*
app.post('/api/send-audio', async(req, res) => {
//  console.dir(req.body); OK
  const { type,audio } = req.body;
  console.log("type before audioData:"+type);
  console.log("audio Data:"+audio);

  tag = 1;

  console.log("Begin saving to file...");
  filePath = "./client-backend/cache/audio"+tag.toString().padStart(4, '0')+".wav";

  try {

    console.log("result of checkFileExists:"+(await checkFileExists(filePath)));
    while(await checkFileExists(filePath)) {
      tag+=1;
      filePath = "./client-backend/cache/audio"+tag.toString().padStart(4, '0')+".wav";
      console.log("tag:"+tag);
    }
    console.log("filePath:",filePath);

    // 将 Base64 字符串转换为 Buffer再写入文件：
    const binAudio = Buffer.from(audio.replace(/^data:.*?;base64,/, ''), 'base64');
    fs.writeFile(filePath, binAudio);

    console.log("文件保存到服务器完成"+filePath);

  }
  catch(error) {
    console.error('保存文件时出错:', error);
  }

  await g_ASRClient.sendAudioChunk(audio);
  res.json({ status: 'Audio chunk sent' });
});

app.post('/api/end-audio', (req, res) => {
  g_ASRClient.endAudio();
  res.json({ status: 'Audio end signal sent' });
});*/

app.post('/api/runASR-audioSegment', async(req, res) => {
//  console.dir(req.body); OK
  const { type,audio } = req.body;
  console.log("type before audioData:"+type);
  console.log("audio Data:"+audio);

  tag = 1;

  console.log("Begin saving to file...");
  filePath = "./client-backend/cache/audio"+tag.toString().padStart(4, '0')+".wav";

  try {

    console.log("result of checkFileExists:"+(await checkFileExists(filePath)));
    while(await checkFileExists(filePath)) {
      tag+=1;
      filePath = "./client-backend/cache/audio"+tag.toString().padStart(4, '0')+".wav";
      console.log("tag:"+tag);
    }
    console.log("filePath:",filePath);

    // 将 Base64 字符串转换为 Buffer再写入文件：
    const binAudio = Buffer.from(audio.replace(/^data:.*?;base64,/, ''), 'base64');
    fs.writeFile(filePath, binAudio);

    console.log("文件保存到服务器完成"+filePath);

  }
  catch(error) {
    console.error('保存文件时出错:', error);
  }

/*  await g_ASRClient.sendAudioChunk(audio);
  res.json({ status: 'Audio chunk sent' });*/
  await new Promise((resolve, reject) => {
    g_ASRClient.sendAudioChunk(audio);
    g_ASRClient.setASRResultRecvCallback(function() {
      g_ASRClient.endAudio();
      g_ASRClient.removeASRResultRecvCallback();
      asrResult = g_ASRClient.getLatestASRResult();
      resolve(asrResult);
    })
  }).then(asrResult => {
    res.json({ text: asrResult });
  }).catch(error => {
    console.error('ASR error:', error);
  })
  
});


/*app.post('/api/upload-file', (req, res) => {
  console.log("!!!Old api!!!!")
  const { file_data, filename } = req.body;
  asrClient.uploadFile(file_data, filename);
  res.json({ status: 'File upload initiated' });
});*/

app.post('/api/runASR-uploadFile', async(req , res) => {
  const { file_data, filename } = req.body;

  await new Promise((resolve, reject) => {
    g_ASRClient.uploadFile(file_data, filename);
    g_ASRClient.setASRResultRecvCallback(function() {
      g_ASRClient.removeASRResultRecvCallback();
      asrResult = g_ASRClient.getLatestASRResult();
      resolve(asrResult);
    })
  }).then(asrResult => {
    res.json({ text: asrResult });
  }).catch(error => {
    console.error('ASR error:', error);
  })
});

// Start server
app.listen(PORT, () => {
  console.log(`Client backend running on http://localhost:${PORT}`);
});